package 每日一题;

public class 股票 {
    //交易次数只有一次
    public int maxProfit(int[] prices) {
        int n=prices.length;
        int[][] dp=new int[n][2];
        for (int i =0;i<n;i++){
            if(i==0){
                dp[i][0]=0;
                dp[i][1]=-prices[i];
                continue;
            }
            dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=Math.max(dp[i-1][1],-prices[i]);

        }
        return dp[n-1][0];
    }
    //不限制交易次数k,那么第二个状态也没必要写
    public int maxProfit1(int[] prices) {
        int n=prices.length;
        int[][] dp=new int[n][2];
        for (int i =0;i<n;i++){
            if(i==0){
                dp[i][0]=0;
                dp[i][1]=-prices[i];
                continue;
            }
            dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

        }
        return dp[n-1][0];
    }
    //限制交易次数k为2次,第二个状态有必要写
    public int maxProfit2(int[] prices) {
        int n=prices.length;
        int[][][] dp=new int[n][2][2];
        for (int i=0;i<n;i++){
            for (int k=2;k>=0;k--){
                if(i==0){
                    dp[i][k][0]=0;
                    dp[i][k][1]=-prices[i];
                    continue;
                }
                dp[i][k][0]=Math.max(dp[i-1][k][0],dp[i-1][k][1]+prices[i]);
                dp[i][k][1]=Math.max(dp[i-1][k][1],dp[i-1][k-1][0]-prices[i]);
            }
        }
        return dp[n-1][1][0];
    }
    //不限制交易次数k,限制交易时间
    public int maxProfit3(int[] prices) {
        int n=prices.length;
        int[][] dp=new int[n][2];
        for (int i =0;i<n;i++){
            if(i==0){
                dp[i][0]=0;
                dp[i][1]=-prices[i];
                continue;
            }
            if(i==1){
                dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
                dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
            }
            dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=Math.max(dp[i-1][1],dp[i-2][0]-prices[i]);

        }
        return dp[n-1][0];
    }
    //k 为正无穷且考虑交易手续费的情况
    public int maxProfit4(int[] prices,int fee) {
        int n=prices.length;
        int[][] dp=new int[n][2];
        for (int i =0;i<n;i++){
            if(i==0){
                dp[i][0]=0;
                dp[i][1]=-prices[i]-fee;
                continue;
            }
            dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]-fee);

        }
        return dp[n-1][0];
    }
}
